package com.promote.hotspot.server.netty.filter;

import com.promote.hotspot.server.counter.KeyCountItem;
import com.promote.hotspot.server.tool.Constant;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.java.Log;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.promote.hotspot.common.model.HotSpotMsg;
import org.promote.hotspot.common.model.KeyCountModel;
import org.promote.hotspot.common.model.MessageType;
import org.promote.hotspot.common.tool.NettyIpUtil;
import org.promote.hotspot.common.tool.SystemClock;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.util.List;

import static com.promote.hotspot.server.counter.CounterManager.COUNTER_QUEUE;

/**
 * 对热点访问次数和总访问次数进行统计
 *
 * @author enping.jep
 * @date 2024/02/29 17:05
 **/
@Component
@Order(4)
@Log
public class StatisticFilter implements INettyMsgFilter {


    @Value("${etcd.serverPath}")
    private String serverPath;

    @Override
    public boolean chain(HotSpotMsg message, ChannelHandlerContext ctx) {
        if (MessageType.REQUEST_HIT_COUNT == message.getMessageType()) {
            //设置appName
            if (StringUtils.isEmpty(message.getAppName())) {
                message.setAppName(serverPath);
            }
            publishMsg(message.getAppName(), message, ctx);
            return false;
        }
        return true;
    }

    private void publishMsg(String appName, HotSpotMsg message, ChannelHandlerContext ctx) {
        List<KeyCountModel> models = message.getKeyCountModels();
        if (CollectionUtils.isEmpty(models)) {
            return;
        }
        long timeOut = SystemClock.now() - models.get(0).getCreateTime();
        //超时5秒以上的就不处理了，因为client是每10秒发送一次，所以最迟15秒以后的就不处理了
        if (timeOut > Constant.TIME_OUT + 10000) {
            log.info("key count timeout " + timeOut + ", from ip : " + NettyIpUtil.clientIp(ctx));
            return;
        }
        //将收到的key放入延时队列，15秒后进行累加并发送
        try {
            COUNTER_QUEUE.put(new KeyCountItem(appName, models.get(0).getCreateTime(), models));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
